'/
' mathutil - version 1.033
' Written 2010 by Anton Berlin.
' 
' =========================================================================
' 
' This program is free software; you can redistribute it and/or modify
' it under the terms of the GNU Lesser General Public License as published
' by the Free Software Foundation; either version 3 of the License.
' 
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU General Public License for more details.
' 
' You should have received a copy of the GNU Lesser General Public License
' along with this program; if not, write to the Free Software
' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
'/

superstrict

import BRL.Math

'// A 2D vector class.
type Vector2

	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Create, setup and return a new vector.
	'// -----------------------------------------------------------------------------------------------------------------
	function create:Vector2(_x:double, _y:double)
	
		local vector:Vector2 = new Vector2;
		vector.X = _x;
		vector.Y = _y;
		return vector;
	
	end function
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Return the magnitude (length) of the vector.
	'// -----------------------------------------------------------------------------------------------------------------
	method getMagnitude:double()
	
		return sqr(X*X + Y*Y);
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Set the coordinates of the vector.
	'// -----------------------------------------------------------------------------------------------------------------
	method setCoordinates(_x:double, _y:double)
	
		X = _x;
		Y = _y;
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Increase the vectors x and y coordinates by a value.
	'// -----------------------------------------------------------------------------------------------------------------
	method increase(val:double)
	
		X :+ val;
		Y :+ val;
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Decrease the vectors x and y coordinates by a value.
	'// -----------------------------------------------------------------------------------------------------------------
	method decrease(val:double)
	
		X :- val;
		Y :- val;
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Add another vector to this vector.
	'// -----------------------------------------------------------------------------------------------------------------
	method add(vector:Vector2)
	
		X :+ vector.X;
		Y :+ vector.Y;
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Subtract another vector from this vector.
	'// -----------------------------------------------------------------------------------------------------------------
	method subtract(vector:Vector2)
	
		X :- vector.X;
		Y :- vector.Y;
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Multiply this vector by another vector.
	'// -----------------------------------------------------------------------------------------------------------------
	method multiply(vector:Vector2)
	
		X :* vector.X;
		Y :* vector.Y;
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Divide this vector by another vector.
	'// -----------------------------------------------------------------------------------------------------------------
	method divide(vector:Vector2)
	
		X :/ vector.X;
		Y :/ vector.Y;
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Copy the values from another vector to this vector.
	'// -----------------------------------------------------------------------------------------------------------------
	method equals(vector:Vector2)
	
		X = vector.X;
		Y = vector.Y;
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Return the angle of this vector.
	'// -----------------------------------------------------------------------------------------------------------------
	method getAngle:double()
	
		return atan2(X, Y);
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Rotate this vector by 'angle' degrees.
	'// -----------------------------------------------------------------------------------------------------------------
	method rotate(angle:double)
	
		X = cos(angle) * X - sin(angle) * Y;
		Y = sin(angle) * X + cos(angle) * Y;
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Normalize the vector.
	'// -----------------------------------------------------------------------------------------------------------------
	method normalize()
	
		local mag:double = getMagnitude();
		if (mag) then
		
			X :/ mag;
			Y :/ mag;
		
		end if
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Invert the coordinates.
	'// -----------------------------------------------------------------------------------------------------------------
	method invert()
	
		X = -X;
		Y = -Y;
	
	end method

	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Clone this vector and return the clone.
	'// -----------------------------------------------------------------------------------------------------------------
	method clone:Vector2()
	
		local vector:Vector2 = new Vector2;
		vector.X = X;
		vector.Y = Y;
		return vector;
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Return a string representation of the vector.
	'// -----------------------------------------------------------------------------------------------------------------
	method toString:string()
	
		return X + "x" + Y;
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Description:
	'// 		Vector coordinates.
	'// -----------------------------------------------------------------------------------------------------------------
	field X:double;
	field Y:double;

end type
